
// import haxe.macro.Expr;
// import haxe.macro.Expr.ExprOf;
// import MathUtil;
// import Setting;

import { MathUtil } from "../../../common/MathUtil";
import { Setting } from "../../../common/Setting";



export class JointMacro {
	// computes CFM_factor and ERP
	// note:
	//     CFM = CFM_factor / mass
	//     deltaImpulse = (1 / (1 / mass + CFM)) * (posError * ERP - velocity - totalImpulse * CFM)
	//                  = mass / (1 + CFM_factor) * (posError * ERP - velocity) - totalImpulse * CFM_factor / (1 + CFM_factor)
	public static computeSoftConstraintParameters(frequency: number, dampingRatio: number, dt: number,
		useSymplecticEuler: boolean): [number, number] {
		var omega: number = 2 * MathUtil.PI * frequency;
		var zeta: number = dampingRatio;
		if (zeta < Setting.minSpringDamperDampingRatio) {
			// limit minimum damping ratio
			zeta = Setting.minSpringDamperDampingRatio;
		}
		var h: number = dt;
		var c: number = 2 * zeta * omega;
		var k: number = omega * omega;

		var outCfmFactor: number, outErp: number;
		if (useSymplecticEuler) {
			// symplectic Euler (conserves energy well but unstable under high frequency)
			outCfmFactor = 1 / (h * c);
			outErp = k / c;
		} else {
			// implicit Euler (tends to lose energy but unconditionally stable)
			outCfmFactor = 1 / (h * (h * k + c));
			outErp = k / (h * k + c);
		}
		return [outCfmFactor, outErp];
	}
}
